package com.example.mq.mqserver.core;

import java.io.Serializable;
import java.util.Arrays;
import java.util.UUID;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: 言初
 * Date: 2024-09-03
 * Time: 15:16
 */
/*
 表示一个要传递的消息
 为了实现序列化和反序列化所以需要让这个类实现  Serializable 接口
 并且实现这个接口不需要重写任何的方法；这个接口是Java标准库自带的方式
 */
public class Message implements Serializable {
    // 属性部分使用一个类对象来表示，在这个类对象对应的类中来罗列属性
    private BasicProperties basicProperties = new BasicProperties();
    // 正文部分使用一个字节数组来表示（所以正文支持二进制数据）
    private byte[] body;

    // 辅助功能，用来验证版本
    private static final long serialVersionUID = 1L;

    // 接下来的是辅助属性
    // 在文件中如何找到这个消息靠的是偏移量，是左闭右开区间
    // message（消息）后续会被存储到文件中（如果持久化存储的话）
    // 一个文件中会有很多个消息，要想确定一个消息在文件中的具体位置：就需要使用下面的这2个偏移量来进行表示
    // [offsetBeg,offsetEnd)
    // 但是这2个属性是不需要被序列化的，因为这2个属性到了内存中才发挥作用（为了方便内存能够快速找到消息的位置）
    // 所以为了不让这2个属性被序列化，就需要使用 关键字  transient 来修饰这两个属性，就不会被Java标准库中的序列化方式给序列化的
    private transient long offsetBeg = 0;// 消息数据的开头距离文件开头的位置偏移（字节）
    private transient long offsetEnd = 0; // 消息数据的结尾距离文件开头的位置偏移（字节）
    // 这个属性表示该消息在文件中是否是有效消息（文件中的消息的删除，采用的是逻辑删除，就是将消息标记为无效）
    // 0x1 表示有效，0x0表示无效
    private byte isvalid = 0x1;

    // 创建一个工厂方法，（作用类似于构造方法）
    // 让工厂方法帮我们封装一下创建message消息对象的过程
    // 这个方法中创建的message对象，会自动生成唯一的messageid
    // 万一routingKey和basicProperties 里的routingKey冲突了，以外面的为主
    public static Message createMessageWithId(String routingKey,BasicProperties basicProperties,byte[] body){
        Message message = new Message();
        if(basicProperties!=null){
            message.setBasicProperties(basicProperties);
        }
        // 此处生成的messageid以 M- 作为前缀
        message.setMessageId("M-"+ UUID.randomUUID());
        message.setRoutingKey(routingKey);
        message.body=body;
        return message;
    }


    // 获取消息id
    public String getMessageId(){
        return basicProperties.getMessageId();
    }
    // set 消息id的方法
    public void setMessageId(String messageId){
        basicProperties.setMessageId(messageId);
    }
    // 获取消息的 RoutingKey
    public String getRoutingKey(){
        return basicProperties.getRoutingKey();
    }
    // set消息的 RoutingKey
    public void setRoutingKey(String routingKey){
        basicProperties.setRoutingKey(routingKey);
    }
    // 获取是否要持久化存储 参数的值
    public int getDeliverMode(){
        return basicProperties.getDeliverMode();
    }
    // set deliverMode 的方法
    public void setDeliverMode(int mode){
        basicProperties.setDeliverMode(mode);
    }


    public BasicProperties getBasicProperties() {
        return basicProperties;
    }

    public void setBasicProperties(BasicProperties basicProperties) {
        this.basicProperties = basicProperties;
    }

    public byte[] getBody() {
        return body;
    }

    public void setBody(byte[] body) {
        this.body = body;
    }

    public long getOffsetBeg() {
        return offsetBeg;
    }

    public void setOffsetBeg(long offsetBeg) {
        this.offsetBeg = offsetBeg;
    }

    public long getOffsetEnd() {
        return offsetEnd;
    }

    public void setOffsetEnd(long offsetEnd) {
        this.offsetEnd = offsetEnd;
    }

    public byte getIsvalid() {
        return isvalid;
    }

    public void setIsvalid(byte isvalid) {
        this.isvalid = isvalid;
    }

    @Override
    public String toString() {
        return "Message{" +
                "basicProperties=" + basicProperties +
                ", body=" + Arrays.toString(body) +
                ", offsetBeg=" + offsetBeg +
                ", offsetEnd=" + offsetEnd +
                ", isvalid=" + isvalid +
                '}';
    }
}
